package cn.qingyun.gis.modules.init.utils;

import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import org.apache.commons.codec.binary.Hex;

import java.security.MessageDigest;
import java.util.*;

public class SignUtil {
    public static final String SIGN = "sign";
    public static final String TIMESTAMP = "timestamp";
    public static final String VERSION = "version";
    public static final String APPID = "appId";
    public static final String CLIENTIP = "clientIp";
    public static final String REQUESTBODY = "requestBody";
    public static final String KEY = "key";
    public static final String DEFAULT_CLIENTIP = "127.0.0.1";
    public static final String DEFAULT_VERSION = "1.0";

    public static String sign(String timestamp, String body, String signKey) {
        String message = buildMessage(DEFAULT_CLIENTIP, DEFAULT_VERSION, timestamp, body, signKey);
        return doSign(message);
    }

    public static String buildMessage(String clientIp, String version, String timestamp, String body, String signKey) {
        TreeMap treeMap = new TreeMap();
        treeMap.put(CLIENTIP, clientIp);
        treeMap.put(VERSION, version);
        treeMap.put(TIMESTAMP, timestamp);
        treeMap.put(REQUESTBODY, body);

        Iterator iterator = treeMap.keySet().iterator();
        StringBuilder builder = new StringBuilder();
        while (iterator.hasNext()) {
            String key = (String) iterator.next();
            String value = (String) treeMap.get(key);
            builder.append(key).append("=").append(value).append("&");
        }
        builder.append(KEY).append("=").append(signKey);
        return builder.toString();
    }

    public static String doSign(String message) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] digest = messageDigest.digest(message.getBytes("utf-8"));
            return new String(Hex.encodeHex(digest)).toUpperCase();
        } catch (Exception e) {
            throw new RuntimeException("error creating sign, reason: " + e.getMessage());
        }
    }

    /**
     * 签名消息发送方法
     */
    public static String messageSend(String msgCode, List<String> numberList, String host, Map<String, Object> msgSketchParamMap, String msgContent) {
        String appId = "8k49VsK3662g2G6y";
        // 调用方参与签名的key，，此为示例值，正式环境另行提供
        String signKey = "pF8048Bt1x78bZ46lCGUX3G5poIRS4J3";
        // 网格通会对调用方的请求时间戳进行校验，默认有效期10分钟
        String timestamp = System.currentTimeMillis() + "";
        //请求报文Map
        Map<Object, Object> bodyMap = new HashMap<>();
        bodyMap.put("requestId", IdUtil.randomUUID());
        bodyMap.put("msgCode", msgCode);
        bodyMap.put("uniqueNumberList", numberList);
        bodyMap.put("msgSketchParamMap", msgSketchParamMap);
        bodyMap.put("msgContent", msgContent);
        // json请求报文示例
        String body = JSONUtil.toJsonStr(bodyMap);
        // 生成签名
        String sign = sign(timestamp, body, signKey);
        //请求地址
        String url = String.format("%s/open/msg/push/send", host);

        // 携带appId、timestamp、clientIp、version、sign等header，请求网格通的接口
        String result = HttpUtil.createPost(url)
                .header(APPID, appId)
                .header(TIMESTAMP, timestamp)
                .header(SIGN, sign)
                .header(CLIENTIP, DEFAULT_CLIENTIP)
                .header(VERSION, DEFAULT_VERSION)
                .body(body)
                .timeout(1000)
                .execute().body();

        /**
         * 接口返回returnCode1000则表示签名校验成功
         * {"returnCode":1000,"message":"成功","dataInfo":null,"nullData":true,"emptyCollection":true,"successAndNotNullData":false,"successAndNotEmptyCollection":false,"success":true,"csrfToken":"08CED8FA71CAFFDE8BD8D3090560621C","chainId":"123cf88d7324b0439eb2ae1c5aad363c"}
         *
         * 返回1001表示验签失败
         * {"returnCode":"1001","message":"request sign valid fail","dataInfo":null,"nullData":true,"emptyCollection":true,"successAndNotNullData":false,"successAndNotEmptyCollection":false,"success":false}
         *
         * 返回1011表示无权限访问该接口
         * {"returnCode":"1011","message":"无权限访问","dataInfo":null,"nullData":true,"emptyCollection":true,"successAndNotNullData":false,"successAndNotEmptyCollection":false,"success":false}
         */
        System.out.println(result);
        return result;
    }

}
